/*!
 * @file font.cpp
 * @brief Ciało font.hh
 */

#include "engine/basic/font.hh"
using namespace std;

/*--------------------------------------------------------------------------*/

font::font(std::string path, int size) :
	path(path), size(size) {

	this->ttffont = TTF_OpenFont(path.c_str(), size);

	if(this->ttffont == NULL){
		log::crash("Nie udało się wczytać czcionki");
	}
}

/*--------------------------------------------------------------------------*/

void font::renderToTexture(texture *tx, std::string text, color cl) const {

	//przy zerowej długości ciągu znakowego sie wykrzacza, więc renderuję spację
	if (text.length() == 0) {
		text = " ";
	}

	SDL_Color sdl_c = { cl.r * 255.0f, cl.g * 255.0f, cl.b * 255.0f, cl.a
			* 255.0f };

	SDL_Surface *surface = TTF_RenderUTF8_Blended(this->ttffont, text.c_str(),
			sdl_c);

	if (surface == NULL) {
		log::crash("Wyrenderowany napis nie jest SDL_Surface" + text);
	}

	GLenum texture_format;
	GLint nOfColors = surface->format->BytesPerPixel;

	if (nOfColors == 4) {
		if (surface->format->Rmask == 0x000000ff)
			texture_format = GL_RGBA;
		else
			texture_format = GL_BGRA;
	} else if (nOfColors == 3) {
		if (surface->format->Rmask == 0x000000ff)
			texture_format = GL_RGB;
		else
			texture_format = GL_BGR;
	} else {
		log::crash("Zły format koloru dla tekstury z napisem.");
	}

	if (tx->gltex) {
		tx->free();
	}

	glGenTextures(1, &tx->gltex);
	glBindTexture(GL_TEXTURE_2D, tx->gltex);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
			texture_format, GL_UNSIGNED_BYTE, surface->pixels);

	const_cast<int &> (tx->w) = surface->w;
	const_cast<int &> (tx->h) = surface->h;

	SDL_FreeSurface(surface);
}

/*--------------------------------------------------------------------------*/

void font::renderToScreen(point2f pos, color cl, std::string content) const {

	texture *tex = new texture();

	this->renderToTexture(tex, content, cl);

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex->gltex);

	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	glBegin(GL_QUADS);

	glTexCoord2f(0.0f, 0.0f);
	glVertex2f(pos.x, pos.y - tex->h);

	glTexCoord2f(1.0f, 0.0f);
	glVertex2f(pos.x + tex->w, pos.y - tex->h);

	glTexCoord2f(1.0f, 1.0f);
	glVertex2f(pos.x + tex->w, pos.y);

	glTexCoord2f(0.0f, 1.0f);
	glVertex2f(pos.x, pos.y);

	glEnd();
	glDisable(GL_TEXTURE_2D);

	delete tex;
}

/*--------------------------------------------------------------------------*/

bool font::status() const {
	return this->ttffont != NULL;
}

/*--------------------------------------------------------------------------*/

string font::getPath() const {
	return this->path;
}

/*--------------------------------------------------------------------------*/

int font::getSize() const {
	return this->size;
}

/*--------------------------------------------------------------------------*/
